]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
folderIcon: Allow dropping application icons
authorGeorges Basile Stavracas Neto <georges.stavracas@gmail.com>
Fri, 28 Jun 2019 22:47:32 +0000 (19:47 -0300)
committerGeorges Basile Stavracas Neto <georges.stavracas@gmail.com>
Thu, 8 Aug 2019 12:11:56 +0000 (09:11 -0300)
Connect to the overview signals related to Drag n' Drop, and
allow dropping application icons in it. Dropping an icon
appends the application id to the folder's GSettings key.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/664

js/ui/appDisplay.js

index 6bd3b1398b854d8d4e377b10a3a0d5ecafb5ad37..5b42f2b10d88d59829b33dc7fe6e3c4de93e3faf 100644 (file)
@@ -81,6 +81,13 @@ function clamp(value, min, max) {
     return Math.max(min, Math.min(max, value));
 }
 
+function _getViewFromIcon(icon) {
+    let parent = icon.actor.get_parent();
+    if (!parent._delegate || !(parent._delegate instanceof BaseAppView))
+        return null;
+    return parent._delegate;
+}
+
 class BaseAppView {
     constructor(params, gridParams) {
         if (this.constructor === BaseAppView)
@@ -240,6 +247,7 @@ var AllView = class AllView extends BaseAppView {
         this.actor = new St.Widget({ layout_manager: new Clutter.BinLayout(),
                                      x_expand: true, y_expand: true });
         this.actor.add_actor(this._scrollView);
+        this._grid._delegate = this;
 
         this._scrollView.set_policy(St.PolicyType.NEVER,
                                     St.PolicyType.EXTERNAL);
@@ -1048,6 +1056,7 @@ var FolderView = class FolderView extends BaseAppView {
         this._grid.x_expand = true;
         this._folder = folder;
         this._parentView = parentView;
+        this._grid._delegate = this;
 
         this.actor = new St.ScrollView({ overlay_scrollbars: true });
         this.actor.set_policy(St.PolicyType.NEVER, St.PolicyType.AUTOMATIC);
@@ -1220,6 +1229,11 @@ var FolderIcon = class FolderIcon {
 
         this.view = new FolderView(this._folder, parentView);
 
+        Main.overview.connect('item-drag-begin',
+                              this._onDragBegin.bind(this));
+        Main.overview.connect('item-drag-end',
+                              this._onDragEnd.bind(this));
+
         this.actor.connect('clicked', this.open.bind(this));
         this.actor.connect('destroy', this.onDestroy.bind(this));
         this.actor.connect('notify::mapped', () => {
@@ -1253,6 +1267,57 @@ var FolderIcon = class FolderIcon {
         return this.view.getAllItems().map(item => item.id);
     }
 
+    _onDragBegin() {
+        this._parentView.inhibitEventBlocker();
+    }
+
+    _onDragEnd() {
+        this._parentView.uninhibitEventBlocker();
+    }
+
+    _canAccept(source) {
+        if (!(source instanceof AppIcon))
+            return false;
+
+        let view = _getViewFromIcon(source);
+        if (!view || !(view instanceof AllView))
+            return false;
+
+        if (this._folder.get_strv('apps').includes(source.id))
+            return false;
+
+        return true;
+    }
+
+    handleDragOver(source) {
+        if (!this._canAccept(source))
+            return DND.DragMotionResult.NO_DROP;
+
+        return DND.DragMotionResult.MOVE_DROP;
+    }
+
+    acceptDrop(source) {
+        if (!this._canAccept(source))
+            return true;
+
+        let app = source.app;
+        let folderApps = this._folder.get_strv('apps');
+        folderApps.push(app.id);
+
+        this._folder.set_strv('apps', folderApps);
+
+        // Also remove from 'excluded-apps' if the app id is listed
+        // there. This is only possible on categories-based folders.
+        let excludedApps = this._folder.get_strv('excluded-apps');
+        let index = excludedApps.indexOf(app.id);
+        if (index >= 0) {
+            excludedApps.splice(index, 1);
+            this._folder.set_strv('excluded-apps', excludedApps);
+        }
+
+        return true;
+    }
+
     _updateName() {
         let name = _getFolderName(this._folder);
         if (this.name == name)